home *** CD-ROM | disk | FTP | other *** search
- /* hemi-cube.c */
- /* written by : Jason R. Wilson 2/21/93 */
-
- /* this package provides routines that implement the hemi-cube algorithm
- for form-factor computation */
-
- #include <math.h>
- #include "render.h"
- #include "vector-matrix.h"
- #include "hemicube.h"
-
- #define HemiRes 100 /* the resolution of the hemi-cube : increase this for more accuracy */
- #define HalfRes 50
- #define PI 3.141592654
-
- /* the hemi-cube itself */
-
- HemiPixel HemiFront [HemiRes][HemiRes];
- HemiPixel HemiRight [HemiRes][HalfRes];
- HemiPixel HemiTop [HemiRes][HalfRes];
- HemiPixel HemiLeft [HemiRes][HalfRes];
- HemiPixel HemiBottom[HemiRes][HalfRes];
-
- /***********************************************************************/
-
- void HemiRenderObjects
- (ObjectCell* ObjectHead,int Case,int winWidth,int winHeight,
- Window ViewWindow)
-
- /* This function projects all of the patches (not elements) of the object onto the viewplane*/
-
-
- {
-
- EdgeListCell EdgeList[winHeight];
- int loop,loop2;
- PolygonCell *CurrentPoly;
- ObjectCell *Object;
- VisVertexCell *FirstVertex;
- VisVertexCell *Traverse;
- double z,zinc;
- Boolean Gone;
-
- Object = ObjectHead;
-
- while (!(Object == NULL))
- {
-
- /* init. EdgeList */
- for (loop = 0;loop < winHeight;loop++)
- EdgeList[loop].OneHere = false;
-
- /* draw each non-culled polygon */
-
- CurrentPoly = Object->PolygonHead;
-
- while (!(CurrentPoly == NULL))
- {
- if (!(CurrentPoly->Culled == true))
- {
-
- /* clip polygon */
-
- ClipPolygon (CurrentPoly,ViewWindow,&Gone);
- if (!(Gone == true))
- {
- /* rasterize edges of polygon */
-
- Traverse = CurrentPoly->VisVertices;
- FirstVertex = Traverse;
-
- while (!(Traverse->Next == NULL))
- {
-
- RasterizeEdge (EdgeList,Traverse,
- Traverse->Next,winWidth,winHeight,ViewWindow);
- Traverse = Traverse->Next;
-
- }
- RasterizeEdge (EdgeList,Traverse,FirstVertex,winWidth,winHeight,
- ViewWindow);
- /* draw scan lines of polygon */
-
- for (loop = 0;loop < winHeight;loop++)
- if (EdgeList[loop].OneHere == true)
- {
- z = EdgeList[loop].Depth1;
- if (!(EdgeList[loop].Depth2 - EdgeList[loop].Depth1 - 1 == 0))
- zinc = (EdgeList[loop].Depth2 - EdgeList[loop].Depth1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- for (loop2 = EdgeList[loop].Xpos1;loop2 < EdgeList[loop].Xpos2;
- loop2++)
- {
- switch (Case) {
- case 1:
- if (z < HemiFront[loop2][loop].depth)
- {
- HemiFront[loop2][loop].depth = z;
- HemiFront[loop2][loop].ID = CurrentPoly->ID;
- }
- break;
- case 2:
- if (z < HemiRight[loop2][loop].depth)
- {
- HemiRight[loop2][loop].depth = z;
- HemiRight[loop2][loop].ID = CurrentPoly->ID;
- }
- break;
- case 3:
- if (z < HemiTop[loop2][loop].depth)
- {
- HemiTop[loop2][loop].depth = z;
- HemiTop[loop2][loop].ID = CurrentPoly->ID;
- }
- break;
- case 4:
- if (z < HemiLeft[loop2][loop].depth)
- {
- HemiLeft[loop2][loop].depth = z;
- HemiLeft[loop2][loop].ID = CurrentPoly->ID;
- }
- break;
- case 5:
- if (z < HemiBottom[loop2][loop].depth)
- {
- HemiBottom[loop2][loop].depth = z;
- HemiBottom[loop2][loop].ID = CurrentPoly->ID;
- }
- break;
-
- z += zinc;
- }
- EdgeList[loop].OneHere = false;
- }
- }
- }
-
- }
- CurrentPoly = CurrentPoly->Next;
- }
-
- Object = Object->Next;
- }
- }
-
- /***********************************************************************/
- void ComputeDeltas ()
- /* computes the delta form-factors */
-
- {
- int i,j;
- double x,y,z;
- double inc;
- double start;
- double deltaA;
- double sumcheck;
-
- sumcheck = 0.0;
- start = -1.0 + 1.0/HemiRes;
- inc = 2.0/HemiRes;
- x = start;
- y = start;
- deltaA = inc*inc;
- /* compute the deltas for the front face */
-
- for (j = 0;j < HemiRes;j++)
- {
- for (i = 0;i < HemiRes;i++)
- {
- HemiFront[i][j].deltaFF = deltaA/(PI*(x*x + y*y + 1)*(x*x + y*y +1));
- x += inc;
- sumcheck += HemiFront[i][j].deltaFF;
- }
- x = start;
- y += inc;
- }
-
- y = start;
- z = 1.0/HemiRes;
-
- for (j = 0;j < HalfRes;j++)
- {
- for (i = 0;i < HemiRes;i++)
- {
- HemiLeft[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
- HemiTop[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
- HemiRight[i][j].deltaFF =z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
- HemiBottom[i][j].deltaFF=z*deltaA/(PI*(y*y + z*z + 1)*(y*y + z*z +1));
- sumcheck += (4.0*HemiLeft[i][j].deltaFF);
- y += inc;
- }
- y = start;
- z += inc;
- }
-
-
- }
-
- /***********************************************************************/
-
- void InitHemiCube ()
-
- /* init. the z-buffer and the ID of the hemi-cube */
-
- {
- int loop, loop2;
-
- /* init. front of cube */
-
- for (loop = 0;loop < HemiRes;loop++)
- for (loop2 = 0;loop2 < HemiRes;loop2++)
- {
- HemiFront[loop][loop2].depth = 10000000.0; /* deep enough ? */
- HemiFront[loop][loop2].ID = 0;
- }
-
- /* init. sides of cube */
-
- for (loop = 0;loop < HemiRes;loop++)
- for (loop2 = 0;loop2 < HalfRes;loop2++)
- {
- HemiRight[loop][loop2].depth = 10000000.0; /* ditto */
- HemiRight[loop][loop2].ID = 0;
- HemiTop[loop][loop2].depth = 10000000.0; /* ditto */
- HemiTop[loop][loop2].ID = 0;
- HemiLeft[loop][loop2].depth = 10000000.0; /* ditto */
- HemiLeft[loop][loop2].ID = 0;
- HemiBottom[loop][loop2].depth = 10000000.0; /* ditto */
- HemiBottom[loop][loop2].ID = 0;
- }
-
- }
-
- /***********************************************************************/
-
- void ProjectPatch (PolygonCell *Poly,double *Row)
- {
- /* this routine projects all of patches onto the hemi-cube surrounding
- the polygon passed in. It puts the row of form-factors into Row */
- Point VRP,center;
- int loop2,loop3;
- VertexListCell *traverse;
- int count;
- Vector u,v,n;
- Vector permu,permv,permn;
- Window ViewWindow;
- double eye;
- Matrix HemiTransform;
-
- /* compute the center of the patch in question */
-
- center.x = 0.0;
- center.y = 0.0;
- center.z = 0.0;
- count = 0;
-
- traverse = Poly->Vertices;
-
- while (!(traverse == NULL))
- {
- count++;
- center.x += traverse->Vertex->WorldPosition.x;
- center.y += traverse->Vertex->WorldPosition.y;
- center.z += traverse->Vertex->WorldPosition.z;
- traverse = traverse->Rest;
- }
-
- center.x /= (double)count;
- center.y /= (double)count;
- center.z /= (double)count;
-
- n = Normalize (Poly->Normal);
-
- v.dx = Poly->Vertices->Vertex->WorldPosition.x - center.x;
- v.dy = Poly->Vertices->Vertex->WorldPosition.y - center.y;
- v.dz = Poly->Vertices->Vertex->WorldPosition.z - center.z;
-
- v = Normalize (v);
- u = Cross (n,v);
- eye = -1.0;
-
- permu = u;
- permv = v;
- permn = n;
-
- VRP.x = center.x + n.dx; /* move VRP up to front face of hemicube */
- VRP.y = center.y + n.dy;
- VRP.z = center.z + n.dz;
-
- InitHemiCube ();
-
-
- /* project down to front of cube */
-
- ProduceTransform (VRP,u,v,n,eye,&HemiTransform);
- TransformView (ObjectHead,HemiTransform);
-
-
- ViewWindow.Wr = 1.0;
- ViewWindow.Wt = 1.0;
- ViewWindow.Wl = -1.0;
- ViewWindow.Wb = -1.0;
-
-
- CullBackFaces (ObjectHead,eye,VRP,n);
- HemiRenderObjects (ObjectHead,1,HemiRes,HemiRes,ViewWindow);
-
-
- /* project down to sides of cube */
-
- ViewWindow.Wb = 0.0; /* only half of a face now */
-
- /* project to right */
-
-
- VRP.x = center.x + permu.dx; /* move VRP to right side of hemicube */
- VRP.y = center.y + permu.dy;
- VRP.z = center.z + permu.dz;
-
- n = permu;
- u = permv;
- v = permn;
-
- ProduceTransform (VRP,u,v,n,eye,&HemiTransform);
- TransformView (ObjectHead,HemiTransform);
- CullBackFaces (ObjectHead,eye,VRP,n);
-
- HemiRenderObjects (ObjectHead,2,HemiRes,HalfRes,ViewWindow);
-
- /* project to top */
-
-
- VRP.x = center.x + (-1)*permv.dx; /* move VRP to top side of hemicube */
- VRP.y = center.y + (-1)*permv.dy;
- VRP.z = center.z + (-1)*permv.dz;
-
- n = Scale (permv,-1);
- u = permu;
- v = permn;
-
- ProduceTransform (VRP,u,v,n,eye,&HemiTransform);
- TransformView (ObjectHead,HemiTransform);
- CullBackFaces (ObjectHead,eye,VRP,n);
-
- HemiRenderObjects (ObjectHead,3,HemiRes,HalfRes,ViewWindow);
-
- /* project to left */
-
-
- VRP.x = center.x + (-1)*permu.dx; /* move VRP to left side of hemicube */
- VRP.y = center.y + (-1)*permu.dy;
- VRP.z = center.z + (-1)*permu.dz;
-
- n = Scale (permu,-1);
- u = Scale (permv,-1);
- v = permn;
-
- ProduceTransform (VRP,u,v,n,eye,&HemiTransform);
- TransformView (ObjectHead,HemiTransform);
- CullBackFaces (ObjectHead,eye,VRP,n);
-
- HemiRenderObjects (ObjectHead,4,HemiRes,HalfRes,ViewWindow);
-
- /* project to bottom */
-
-
- VRP.x = center.x + permv.dx; /* move VRP to bot. side of hemicube */
- VRP.y = center.y + permv.dy;
- VRP.z = center.z + permv.dz;
-
- n = permv;
- u = Scale (permu,-1);
- v = permn;
-
- ProduceTransform (VRP,u,v,n,eye,&HemiTransform);
- TransformView (ObjectHead,HemiTransform);
- CullBackFaces (ObjectHead,eye,VRP,n);
-
- HemiRenderObjects (ObjectHead,5,HemiRes,HalfRes,ViewWindow);
-
- /* now go through and sum up the patch-to-patch ff's ! */
-
-
- /* sum front of cube contribution */
-
- for (loop2 = 0;loop2 < HemiRes;loop2++)
- for (loop3 = 0;loop3 < HemiRes;loop3++)
- {
- if (!(HemiFront[loop2][loop3].ID == 0))
- Row[(HemiFront[loop2][loop3].ID)-1] +=
- HemiFront[loop2][loop3].deltaFF;
- }
-
- /* sum sides of cube */
-
- for (loop2 = 0;loop2 < HemiRes;loop2++)
- for (loop3 = 0;loop3 < HalfRes;loop3++)
- {
- if (!(HemiRight[loop2][loop3].ID == 0))
- Row[(HemiRight[loop2][loop3].ID)-1] +=
- HemiRight[loop2][loop3].deltaFF;
- if (!(HemiTop[loop2][loop3].ID == 0))
- Row[(HemiTop[loop2][loop3].ID)-1] +=
- HemiTop[loop2][loop3].deltaFF;
- if (!(HemiLeft[loop2][loop3].ID == 0))
- Row[(HemiLeft[loop2][loop3].ID)-1] +=
- HemiLeft[loop2][loop3].deltaFF;
- if (!(HemiBottom[loop2][loop3].ID == 0))
- Row[(HemiBottom[loop2][loop3].ID)-1] +=
- HemiBottom[loop2][loop3].deltaFF;
- }
-
- }
-
-
- /*----------------------------------------------------------------------*/
-
-
-
-
-
-